#include "qt_hecp.h"
#ifdef __cplusplus
extern "C" {
#endif
int _log_level;///add by Gaoy--20180515
typedef struct hecp_cli_struct {
    int cid;
    int type;/*TCP|UDP*/
    int sockfd;
    struct hecp_request_struct *req;
}hecp_cli_t;

log_query_struct* log_head=NULL;///add by Gaoy--20180116

static int hecp_version_major=0;
static int hecp_version_minor=1;
static int hecp_revision=0;
static char hecp_version_str[32]="";

static char *mname[]=
    {
        "GET","POST","QUERY","DELETE"
    };

static char* hecp_method_name(int method){
    return mname[method-1];
    }

#define HECP_CLI_ARRAY_SIZE 8
static hecp_cli_t *hecp_cli_array[HECP_CLI_ARRAY_SIZE]=
{
    NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL
};
static hecp_cli_t* hecp_cli_get(int cid){
    return hecp_cli_array[cid];
}

static int hecp_cli_build_request_message(hecp_cli_t *cli_p){
    hecp_request_t *req_p=cli_p->req;

    snprintf(req_p->sbuf,sizeof(req_p->sbuf)-1,"%s %s HECP/%d.%d\r\n",
        hecp_method_name(req_p->method),req_p->URL,
        hecp_version_major,hecp_version_minor);
    /*head&entity seperator blank line.*/
    strcat(req_p->sbuf,"\r\n");

    if(strlen(req_p->entity))
        strcat(req_p->sbuf,req_p->entity);
    else
        strcat(req_p->sbuf,"\r\n");
    strcat(req_p->sbuf,"\r\n");

    req_p->slen=strlen(req_p->sbuf);

//    if(be_debug){
//        printf("%s",req_p->sbuf);
//    }
    return 0;
}
static int hecp_cli_send(hecp_cli_t *cli_p,
struct timeval *timeout){
    fd_set wfds;
    struct timeval tout;
    int retval;

    FD_ZERO(&wfds);
    FD_SET(cli_p->sockfd,&wfds);
    if ( timeout ) {
        tout.tv_sec=timeout->tv_sec;
        tout.tv_usec=timeout->tv_usec;
    } else {
        tout.tv_sec=1;
        tout.tv_usec=0;
    }

select_again:
    retval=select(cli_p->sockfd+1,NULL,&wfds,NULL,&tout);
    if ( retval<=0 || !FD_ISSET(cli_p->sockfd,&wfds) ) {

        if(retval==-1 && errno==EINTR){
           // DBG(HECP_PREFIX"select(EINTR), select again");
            goto select_again;
        }

        //xeLOG_ERR(HECP_PREFIX"select FAIL, errno=%d errmsg=%s",errno,strerror(errno));

        return -1;
    }
#if defined(__unix__)
    retval=send(cli_p->sockfd,cli_p->req->sbuf,
        cli_p->req->slen,MSG_NOSIGNAL);
#elif defined(_WIN32)
    retval=send(cli_p->sockfd,cli_p->req->sbuf,
        cli_p->req->slen,0);
#endif
    if ( retval<=0 ) {
       // xeLOG_ERR(HECP_PREFIX"send FAIL, errno=%d errmsg=%s",errno,strerror(errno));
        return -1;
    }
    return retval;
}

static int hecp_cli_recv(hecp_cli_t *cli_p, struct timeval *timeout){
         fd_set rfds;
         struct timeval tout;
         int retval;
         while (1) {
             FD_ZERO(&rfds);
             FD_SET(cli_p->sockfd,&rfds);
             if ( timeout ) {
                 tout.tv_sec=timeout->tv_sec;
                 tout.tv_usec=timeout->tv_usec;
             } else {
                 tout.tv_sec=1;
                 tout.tv_usec=0;
             }

 select_again:
             retval=select(cli_p->sockfd+1,&rfds,NULL,NULL,&tout);
             if ( retval<=0 || !FD_ISSET(cli_p->sockfd,&rfds) ) {

                 if(retval==-1 && errno==EINTR){
                     //DBG(HECP_PREFIX"select(EINTR), select again");
                     goto select_again;
                 }

                // xeLOG_ERR(HECP_PREFIX"select FAIL, errno=%d errmsg=%s",errno,strerror(errno));
                 break;
             }
             retval=recv(cli_p->sockfd,cli_p->req->rbuf+cli_p->req->rlen,
                 sizeof(cli_p->req->rbuf)-cli_p->req->rlen,0);
             if ( retval==-1 ) {
              //   xeLOG_ERR(HECP_PREFIX"recv FAIL, errno=%d errmsg=%s",errno,strerror(errno));
                 break;
             }
             if(retval==0)break;
             cli_p->req->rlen+=retval;
         }

//                                 if(be_debug)
//                                     printf("%s",cli_p->req->rbuf);

         return cli_p->req->rlen;
 }

static int hecp_cli_parse_response_head_status_code(hecp_cli_t *cli_p){
        char *cptr;
        hecp_request_t *req_p=NULL;

        req_p=cli_p->req;
        cptr=strchr(req_p->rbuf,' ');
        if ( cptr==NULL ) {
//            if ( be_debug ) {
//                printf("%s: cant get status code!\n",__FUNC__);
//            }
            return -1;
        }

        while ( !isdigit(*cptr) ) {
            cptr++;
        }

        req_p->status=atoi(cptr);

        return 0;
    }

static int hecp_cli_parse_response_head(hecp_cli_t *cli_p){
    int retval;

    retval=hecp_cli_parse_response_head_status_code(cli_p);

    return retval;
}

/*
* Helper Function: hecp_entity_calloc
************************************************
* Allocate a new empty entity.
*
*	Return:
*		new pointer: success;
*		NULL:	fail;
*/
static struct hecp_entity_struct*
    hecp_entity_calloc(const char *key,
    int key_len,
    const char *value,
    int value_len) {
        struct hecp_entity_struct *ety_p=NULL;

        ety_p = (struct hecp_entity_struct*)calloc(1, sizeof(struct hecp_entity_struct));
        if ( ety_p==NULL ) {
            //xeLOG_ERR(HECP_PREFIX"calloc FAIL, errno=%d errmsg=%s",errno,strerror(errno));
            return NULL;
        }

        ety_p->key = (char*)calloc(1, key_len+1);
        if ( ety_p->key==NULL ) {
            //xeLOG_ERR(HECP_PREFIX"calloc FAIL, errno=%d errmsg=%s",errno,strerror(errno));
            goto errout;
        }
        memcpy(ety_p->key, key,key_len);

        ety_p->value = (char*)calloc(1, value_len+1);
        if ( ety_p->value==NULL ) {
           // xeLOG_ERR(HECP_PREFIX"calloc FAIL, errno=%d errmsg=%s",errno,strerror(errno));
            goto errout;
        }
        memcpy(ety_p->value, value, value_len);

        return ety_p;

errout:
        if ( ety_p->key ) {
            free(ety_p->key);
        }
        if ( ety_p->value ) {
            free(ety_p->value);
        }
        return NULL;
}


static int hecp_cli_parse_response_entities(hecp_cli_t *cli_p){
        char *cptr=NULL,*cptr_es=NULL,*cptr_ee=NULL;
        char *cptrs=NULL,*cptre=NULL;
        int key_len,value_len;
        hecp_entity_t *ent_p=NULL,*ent_new_p=NULL;
        hecp_request_t *req_p=cli_p->req;

        cptr=strstr(req_p->rbuf,"\r\n\r\n");
        if ( cptr==NULL ) {
//            if ( be_debug ) {
//                printf("%s: cant get head&entity separator!\n",__FUNC__);
//            }
            return -1;
        }
        cptr+=4;

        /*entity base*/
        cptr_es=cptr;
        cptr=strstr(cptr_es,"\r\n\r\n");
        /*entity end*/
        if ( cptr ) {
            cptr_ee=cptr+2;
        } else {
            cptr_ee=req_p->rbuf+req_p->rlen;
        }

        cptrs=cptr_es;
        while ( cptrs && cptrs<cptr_ee ) {
            if ( isspace(*cptrs) )break;

            cptr=strstr(cptrs,"\r\n");
            if ( cptr==NULL )break;

            cptre=cptr;

            cptr=strchr(cptrs,'=');
            if ( cptr==NULL )break;

            key_len=cptr-cptrs;

            cptr+=1;
            value_len=cptre-cptr;

            ent_new_p=hecp_entity_calloc(cptrs,key_len,cptr,value_len);
            if ( ent_new_p==NULL ) {
                req_p->ety_p=ent_p;
                return -1;
            }
            ent_new_p->next=ent_p;
            ent_p=ent_new_p;

            cptrs=cptre+2;
        }

        req_p->ety_p=ent_p;
        return 0;
    }

static int hecp_cli_parse_response(hecp_cli_t *cli_p){
    int retval;
    retval=hecp_cli_parse_response_head(cli_p);
    retval=hecp_cli_parse_response_entities(cli_p);

    return retval;
}
///--------------------------------------------------------------------------------------
int hecp_cli_set_request_head_URL(IN int cid,
        IN const char *URL){
            hecp_cli_t *cli_p=hecp_cli_get(cid);
            hecp_request_t *req_p=NULL;

            if ( cli_p==NULL ) {
                return -1;
            }
            req_p=cli_p->req;

            //req_p->URL=strdup(URL);
            req_p->URL = calloc(1,strlen(URL)+1);
            if ( req_p->URL==NULL ) {
                //xeLOG_ERR(HECP_PREFIX"calloc FAIL, errno=%d errmsg=%s",errno,strerror(errno));
                return -1;
            }
            memcpy(req_p->URL,URL,strlen(URL));
            return 0;
    }
int hecp_cli_set_request_head_method(IN int cid,
    IN int method){
        hecp_cli_t *cli_p=hecp_cli_get(cid);
        hecp_request_t *req_p=NULL;

        if ( cli_p==NULL ) {
            return -1;
        }
        req_p=cli_p->req;

        if ( method==HECP_METHOD_GET ||
            method==HECP_METHOD_POST ||
            method==HECP_METHOD_QUERY ||
            method==HECP_METHOD_DELETE ) {
                req_p->method=method;
                return 0;
        }
        return -1;
}
int hecp_cli_add_request_entity(IN int cid,
        IN const char *key,
        IN const char *value){
            hecp_cli_t *cli_p=hecp_cli_get(cid);
            hecp_request_t *req_p=NULL;
            int buflen;
            char bufline[128]="";

            if ( cli_p==NULL ) {
                return -1;
            }
            req_p=cli_p->req;
            snprintf(bufline,sizeof(bufline)-1,"%s=%s\r\n",key,value);
            buflen = strlen(bufline);
            if(sizeof(req_p->entity)-(size_t)req_p->elen > (size_t)buflen)//edit by hanln
                {
                    strcat(req_p->entity, bufline);
                    req_p->elen+=buflen;
                    return 0;
                }
                else
                {
                    ///xeLOG_ERR(HECP_PREFIX"too large entity.");
                    return -1;
                }
    }

/*
* Helper Function: hecp_entity_free
************************************************
* Free a entity.
*/
static void
    hecp_entity_free(struct hecp_entity_struct *ety_p){
        struct hecp_entity_struct *nety_p=NULL;

        while ( ety_p ) {
            nety_p=ety_p->next;

            if ( ety_p->key )
                free(ety_p->key);
            if ( ety_p->value )
                free(ety_p->value);

            free(ety_p);

            ety_p=nety_p;
        }

        return;
}


static hecp_cli_t* hecp_cli_new(void){
    hecp_cli_t *cli_p=NULL;

    cli_p=calloc(1,sizeof(hecp_cli_t));
    if ( cli_p==NULL ) {
        return NULL;
    }
    cli_p->req=calloc(1,sizeof(struct hecp_request_struct));
    if ( cli_p->req==NULL ) {
        free(cli_p);
        return NULL;
    }
    return cli_p;
}


int hecp_cli_transmit(IN int cid, struct timeval *timeout){
    hecp_cli_t *cli_p=hecp_cli_get(cid);
    int retval;

    if ( cli_p==NULL ) {
        return -1;
    }

    hecp_cli_build_request_message(cli_p);

    retval=hecp_cli_send(cli_p,timeout);
    if ( retval<=0 ) {
        return -1;
    }
    retval=hecp_cli_recv(cli_p,timeout);
    if ( retval<0 ) {
        return -1;
    }
    if(retval==0){
       // xeLOG_ERR(HECP_PREFIX"nothing received, BAD!");
        return -1;
    }
    retval=hecp_cli_parse_response(cli_p);
    if ( retval==-1 ) {
        return -1;
    }
    return 0;
}

static pthread_mutex_t hecp_cli_array_locker = PTHREAD_MUTEX_INITIALIZER;

static void hecp_cli_remove(hecp_cli_t *cli_p){
    QtHecp_mutex_lock(&hecp_cli_array_locker);
    hecp_cli_array[cli_p->cid]=NULL;
    QtHecp_mutex_unlock(&hecp_cli_array_locker);
    return;
}

static int hecp_cli_insert(hecp_cli_t *cli_p){
    int i;
    QtHecp_mutex_lock(&hecp_cli_array_locker);
    for ( i=0; i<HECP_CLI_ARRAY_SIZE;i++ ) {
        if ( hecp_cli_array[i]==NULL ) {
            hecp_cli_array[i]=cli_p;
            cli_p->cid=i;
            QtHecp_mutex_unlock(&hecp_cli_array_locker);
            return 0;
        }
    }

    QtHecp_mutex_unlock(&hecp_cli_array_locker);
    return -1;
}

static void hecp_cli_free(hecp_cli_t *cli_p){
        if(cli_p->req->ety_p){
            hecp_entity_free(cli_p->req->ety_p);
        }

        if ( cli_p->req->URL ){
            free(cli_p->req->URL);
        }

        free(cli_p->req);
        if ( cli_p->sockfd>0 )net_close(cli_p->sockfd);
        free(cli_p);
        return;
    }



void hecp_cli_close(IN int cid){
    hecp_cli_t *cli_p=hecp_cli_get(cid);
    if(cli_p==NULL)
        return;
    hecp_cli_remove(cli_p);
    hecp_cli_free(cli_p);
    return;
}

int hecp_cli_get_response_head_status_code(IN int cid){
    hecp_cli_t *cli_p=hecp_cli_get(cid);
    hecp_request_t *req_p=NULL;

    if ( cli_p==NULL ) {
        return -1;
    }
    req_p=cli_p->req;

    return req_p->status;
}

int hecp_cli_get_response_entity_first(IN int cid){
    hecp_cli_t *cli_p=hecp_cli_get(cid);
    hecp_request_t *req_p=NULL;

    if ( cli_p==NULL ) {
        return -1;
    }
    req_p=cli_p->req;

    req_p->ety_cp=req_p->ety_p;
    return 0;
}

int hecp_cli_get_response_entity_next(IN int cid,
    OUT char *key,
    IN OUT int *key_len,
    OUT char *value,
    IN OUT int *value_len){
        hecp_cli_t *cli_p=hecp_cli_get(cid);
        hecp_request_t *req_p=NULL;
        struct hecp_entity_struct *ety_cp;

        if ( cli_p==NULL ) {
            return -1;
        }
        req_p=cli_p->req;

        memset(key,0,*key_len);
        memset(value,0,*value_len);

        ety_cp=req_p->ety_cp;
        if ( ety_cp==NULL )
            return -1;/*no entity or loop end*/

        strncpy(key,ety_cp->key,*key_len);
        *key_len=strlen(key);
        strncpy(value,ety_cp->value,*value_len);
        *value_len=strlen(value);

        req_p->ety_cp=ety_cp->next;
        return 0;
}

int hecp_cli_open_TCP(IN const char *dst_addr, IN int dst_port)
{
    hxSDK_socket_t sockfd;
    int retval=0;
    struct sockaddr_in dstaddr;
    hecp_cli_t *cli_p=NULL;
#if defined(__unix__)
    struct timeval timeo = {2, 0};
#endif

#if defined(_WIN32)    //add by Gaoy---20171010---start
    u_long nonblock = 1;
    int err = -1,len;
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);
#endif          //add by Gaoy---20171010----end

    sockfd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if (sockfd==-1)
    {
        printf("socket FAIL, errno=%d errmsg=%s",errno,strerror(errno));
        return -1;
    }
    dstaddr.sin_family=AF_INET;
#if defined(__unix__)
    retval=inet_aton(dst_addr, &dstaddr.sin_addr);
    if (retval==0)
    {
        //xeLOG_ERR(HECP_PREFIX"incorrect dest IP(%s)",dst_addr);
        printf("incorrect dest IP(%s)",dst_addr);
        net_close(sockfd);
        return -1;
    }
#elif defined(_WIN32)
    dstaddr.sin_addr.S_un.S_addr=inet_addr(dst_addr);
#endif
    dstaddr.sin_port=htons((u_short)dst_port);

#if defined(__unix__)
    setsockopt(sockfd, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeo, sizeof(timeo));
connect_again:
    retval=connect(sockfd, (struct sockaddr*)&dstaddr, sizeof(dstaddr));

    if (retval==-1)
    {
        if(errno==EINTR){
            //DBG(HECP_PREFIX"connect(EINTR), connect again");
            goto connect_again;
        }
        net_close(sockfd);
        return -1;
    }


#elif defined(_WIN32)
    retval = ioctlsocket(sockfd,FIONBIO,&nonblock);
connect_again:
    retval=connect(sockfd, (struct sockaddr*)&dstaddr, sizeof(dstaddr));

    if (retval==-1)
    {
        fd_set wfds;
        struct timeval tv;
        if(errno==EINTR){
            //DBG(HECP_PREFIX"connect(EINTR), connect again");
            goto connect_again;
        }
        tv.tv_sec = 2;
        tv.tv_usec = 0;
        FD_ZERO(&wfds);
        FD_SET(sockfd,&wfds);
        retval = select(sockfd+1,NULL,&wfds,NULL,&tv);
        if (retval > 0)
        {
            len = sizeof(int);
            getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&err, &len);
            if (err)
            {
                net_close(sockfd);
                return -1;
            }
        }
        else
        {
            net_close(sockfd);
            return -1;
        }
    }
#endif


    cli_p=hecp_cli_new();
    if (cli_p==NULL)
    {
        goto err_out;
    }
    retval=hecp_cli_insert(cli_p);
    if (retval==-1)
    {
        goto err_out;
    }

    cli_p->type=HECP_CLI_TYPE_TCP;
    cli_p->sockfd=sockfd;

    return cli_p->cid;

    err_out: if (sockfd>0)
        net_close(sockfd);
    if (cli_p)
        hecp_cli_free(cli_p);
    return -1;
}







///add by Gaoy---20180112
int QtHecp_mutex_init(hxSDK_mutex_t * hMutex)
{
#if defined(__unix__)
    pthread_mutex_init(hMutex,PTHREAD_PROCESS_PRIVATE);
#elif defined(_WIN32)
    ;///WaitForSingleObject(*hMutex, 0); /* == WAIT_TIMEOUT; */
#endif
    return 0;
}


int QtHecp_mutex_lock(hxSDK_mutex_t * hMutex)
{
#if defined(__unix__)
    hxSDK_mutex_lock(hMutex);
#elif defined(_WIN32)
    WaitForSingleObject(*hMutex, 0); /* == WAIT_TIMEOUT; */
#endif
    return 0;
}

int QtHecp_mutex_unlock(hxSDK_mutex_t * hMutex)
{
#if defined(__unix__)
    hxSDK_mutex_unlock(hMutex);
#elif defined(_WIN32)
    ReleaseMutex(*hMutex);
#endif
    return 0;
}

////add by Gaoy----20180112---start

static int del_log_list(log_query_struct*object)
{
    log_query_struct*del=log_head;
    log_query_struct*del_pre=NULL;
    while(del)
    {
        if(del==object)
        {
            log_data_struct*data=del->data;

            if(del_pre)
            {
                del_pre->next=del->next;
            }
            else
            {
                log_head=log_head->next;
            }

            while(data)
            {
                log_data_struct*del=data;
                data=data->next;
                free(del);
            }
            free(del);
            break;
        }
        del_pre=del;
        del=del->next;
    }
    return 0;
}
int QtHecp_socket_close(hxSDK_socket_t sockfd)
{
    if(sockfd>0)
#if	defined(WIN32) || defined(_WIN32_WCE)
        return closesocket(sockfd);
#else
        return close(sockfd);
#endif
    return -1;
}
static void change_bit(unsigned long *param)
{
    char tmp[4],tmp2[4];
    memcpy(tmp,param,4);
    int i=0;
    for(i=0;i<4;i++)
    {
        tmp2[i]=tmp[3-i];
    }
    memcpy(param,tmp2,4);
}
static void change_bits(linE_lres_t*param)
{
    change_bit(&(param->level));
    change_bit(&(param->magiK));
    change_bit((unsigned long*)&(param->module));
    change_bit((unsigned long*)&(param->tick.year));
    change_bit((unsigned long*)&(param->tick.mon));
    change_bit((unsigned long*)&(param->tick.day));
    change_bit((unsigned long*)&(param->tick.hour));
    change_bit((unsigned long*)&(param->tick.min));
    change_bit((unsigned long*)&(param->tick.sec));
}

/////仅仅使用TCP PASSIVE 模式获取logs
///所接收到的logs数据是存储到了 parma->data
static void __getLogs( log_query_struct *param)
{
    //printf("recv_data_thread\n");
    hxSDK_mutex_t mutex_log;
    log_query_struct *node=param;
    QtHecp_mutex_init(&mutex_log);///初始化互斥锁

    int result=-1;
    hxSDK_socket_t recv_sock_fd=node->sock_fd;//edit by hanln

    if(node->proto==HX_SDESC_PROTO_TCP&&node->mode==HX_SDESC_MODE_PASSIVE)
    {
        struct sockaddr_in server;
        int server_len=sizeof(server);//edit by hanln
        server.sin_family=AF_INET;
        server.sin_port=htons((u_short)node->port);//edit by hanln
        server.sin_addr.s_addr=inet_addr(node->ip);
        result=connect(node->sock_fd,(struct sockaddr*)(&server),server_len);
        if(result==-1)
        {
            QtHecp_socket_close(node->sock_fd);//edit by hanln
            QtHecp_mutex_lock(&mutex_log);
            del_log_list(node);
            QtHecp_mutex_unlock(&mutex_log);
        }
    }
#if 0 ///仅仅支持 TCP PASSIVE模式获取logs
    else if(node->proto==HX_SDESC_PROTO_TCP&&node->mode==HX_SDESC_MODE_PORT)
    {
        fd_set fds;
        struct timeval tv;

        FD_ZERO(&fds);
        FD_SET(node->sock_fd,&fds);

        tv.tv_sec=5;
        tv.tv_usec=0;
        select(node->sock_fd+1,&fds,NULL,NULL,&tv);
        if(FD_ISSET(node->sock_fd,&fds))
        {
            struct sockaddr_in client_addr;
            //socklen_t socklen=sizeof(struct sockaddr_in);
            hxSDK_socklen_t socklen=sizeof(struct sockaddr_in);
            recv_sock_fd=accept(node->sock_fd, (struct sockaddr *)(&client_addr), &socklen);
            result=0;
        }
    }
    else//udp
    {
        result=0;
    }
#endif
    if(result>=0)
    {
        char recv_buf[1024];
        int save_len=0;
        int recv_len=0;
        //int flush_flag=0;
        while(1)
        {

            fd_set fds;
            struct timeval tv;
            hxSDK_socket_t max_fd;

            FD_ZERO(&fds);
            FD_SET(recv_sock_fd,&fds);
            //FD_SET((unsigned int)node->flush_signal[0],&fds);

            tv.tv_sec=5;
            tv.tv_usec=0;
            max_fd=recv_sock_fd;//edit by hanln
//            if (max_fd<(unsigned int)node->flush_signal[0])//edit by hanln
//            {
//                max_fd=node->flush_signal[0];
//            }
            select(max_fd+1,&fds,NULL,NULL,&tv);
//            if(FD_ISSET(node->flush_signal[0],&fds))
//            {
//                flush_flag=1;
//                break;
//            }
//            memset(recv_buf,0,1024);///add by Gaoy--20180115
            if(FD_ISSET(recv_sock_fd,&fds))
            {
#if defined(__unix__)
                recv_len=read(recv_sock_fd,recv_buf+save_len,sizeof(recv_buf)-save_len);
#endif
#if defined(_WIN32)
                recv_len=recv(recv_sock_fd,recv_buf+save_len,sizeof(recv_buf)-save_len,0);//edit by hanln
#endif
                save_len+=recv_len;
                if(recv_len>0)
                {
                    unsigned long top;
                    int i;

                    for(i=0;i<save_len;i++)
                    {
                        memcpy(&top,recv_buf,sizeof(top));
#if defined(__unix__)
    #if (__BYTE_ORDER != __BIG_ENDIAN)
                        change_bit(&top);
    #endif
#endif
#if defined(_WIN32)
                        change_bit(&top);///Host-->local
#endif
                        if(top==HX_LINE_LOG_RESPONSE_MAGIK)
                        {
                            int i=0;
                            int count=save_len/sizeof(linE_lres_t);
                            while(1)
                            {
                                if(node->data_len<100)
                                {
                                    break;///数据量小于100个数据包
                                }
#if defined(__unix__)
                                usleep(10000);//10ms
#endif
#if defined(_WIN32)
                                Sleep(10);////数据量大于100个数据包的话，暂停此线程
#endif
                            }
                             QtHecp_mutex_lock(&mutex_log);

                            for(i=0;i<count;i++)
                            {
                                log_data_struct*one=malloc(sizeof(log_data_struct));
                                if (one)
                                {
                                    memset(one, 0, sizeof(log_data_struct));
                                    memcpy(&(one->msg),recv_buf+i*sizeof(linE_lres_t),sizeof(linE_lres_t));
#if defined(__unix__)
    #if (__BYTE_ORDER != __BIG_ENDIAN)
                                        change_bits(&(one->msg));
    #endif
#endif
#if defined(_WIN32)
                                    //add by hanln 2009-06-01
                                    change_bits(&(one->msg));
                                    //end add by hanln 2009-06-01
#endif
                                    //memcpy(recv_buf,recv_buf	+sizeof(linE_lres_t),sizeof(linE_lres_t));
                                    //save_len-=sizeof(linE_lres_t);
                                    if (node->data)
                                    {
                                        one->next=node->data;
                                    }
                                    node->data=one;
                                    (node->data_len)++;///node->data_len存储数据包的个数
                                }
                            }
                            memcpy(recv_buf,recv_buf+sizeof(linE_lres_t)*count,save_len-sizeof(linE_lres_t)*count);
                            save_len=save_len-sizeof(linE_lres_t)*count;
                            QtHecp_mutex_unlock(&mutex_log);
                            break;
                        }
                        else
                        {
                            //del first char
                            memcpy(recv_buf,recv_buf+1,save_len-1);
                            save_len--;
                        }
                    }
                }
                else
                {
                    break;
                }
            }
            else
            {
                break;
            }
        }

        if(recv_sock_fd>=0&&recv_sock_fd!=node->sock_fd)
        {
            //close(recv_sock_fd);
            QtHecp_socket_close(recv_sock_fd);//edit by hanln
        }
            //close(node->sock_fd);
            //printf("hxSDK_socket_close %d\n",node->sock_fd);
            QtHecp_socket_close(node->sock_fd);//edit by hanln
//#if defined(__unix__)
//        if(node->flush_signal[0]>0)
//        {
//            close(node->flush_signal[0]);
//        }
//        if(node->flush_signal[1]>0)
//        {
//            close(node->flush_signal[1]);
//        }
//#endif
//#if defined(_WIN32)
//        if(node->flush_signal[0]>0)
//        {
//            closesocket(node->flush_signal[0]);
//        }
//        if(node->flush_signal[1]>0)
//        {
//            closesocket	(node->flush_signal[1]);
//        }
//#endif
        //int i=0;
//        if (flush_flag==0)
//        {
            int i=0;
            for (i=0; i<100; i++)
            {
                if (node->data==NULL)
                {
                    break;
                }
#if defined(__unix__)
                usleep(10000);//10ms
#endif
#if defined(_WIN32)
                Sleep(5);
#endif
            }
//        }
        QtHecp_mutex_lock(&mutex_log);
        del_log_list(node);
        QtHecp_mutex_unlock(&mutex_log);
    }
#if defined(__unix__)
    pthread_detach(pthread_self());
#endif
#if defined(_WIN32)
    //hxSDK_thread_join((hxSDK_thread_t)GetCurrentThreadId(),NULL);
#endif
}

///在使用__getLogs前必须创建loglist
log_query_struct* Getlogs(const char *ip,const int port)
{
//    int ret=-1;
    int sockfd= -1;
    sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);///创建socket
    if(sockfd == -1)
    {
        printf("create socket fail");
        return NULL;
    }
    log_query_struct*node=(log_query_struct*)malloc(sizeof(log_query_struct));
    if (node)
    {
        memset(node, 0, sizeof(log_query_struct));
        node->sock_fd=sockfd;
        snprintf(node->ip, sizeof(node->ip)-1, "%s", ip);
        node->port=port;
        node->mode=HX_SDESC_MODE_PASSIVE;
        node->proto=HX_SDESC_PROTO_TCP;
        node->data=NULL;
        node->data_len=0;
        node->next=NULL;
//        ret=pipe(node->flush_signal);
        if (log_head)///log_head 全局变量
        {
            log_query_struct*tail=log_head;
            while (tail->next)
            {
                tail=tail->next;
            }
            tail->next=node;
        }
        else
        {
            log_head=node;
        }
        __getLogs(node);////获取日志信息
        hxSDK_mutex_t mutex_null;
        QtHecp_mutex_init(&mutex_null);

        while(1)
        {
            QtHecp_mutex_lock(&mutex_null);
            if(node->data != NULL)
            {
                #if defined(__unix__)
                           usleep(10000);//10ms
                #endif
                #if defined(_WIN32)
                           Sleep(1);
                #endif
            }
            else
                return NULL;
            QtHecp_mutex_unlock(&mutex_null);
        }////再数据结构未空的时候，此线程阻塞，等待主线程读取数据

//        if(node->data != NULL)
//            return node;////
//        else
//            return NULL;
    }
    else
    {
        return NULL;
    }
}


////add by Gaoy----20180112---end

#ifdef __cplusplus
};
#endif
